'''
Created on Aug 13, 2012

@author: petrina
'''

from datastructure.agg_record import * 
from datastructure.record_list import *
from datastructure.interval_list import * 
import logging
import math

class Indicator(object):
    '''
    this class is abstract and represents one indicator.
    
    The indicator-subclasses handle the data.
    The indicator may calculate its values for each time interval and
    export the data as csv or png.
    '''


    def __init__(self):
        
        # default values
        self._intervals = 96
                     
        # contains indicator values of the most recent call of calculate()
        self._values = None 
        
        # default name of the indicator
        self._name = 'Index'
        self._mr_name = 'idx'
        self._unit = 'units'   
             
        # titles for plotting and exporting
        self._title = self._name
        self._exp_title = self._mr_name
        
        logging.debug("Indicator: created Indicator")




    
    #-----------------------getter- and setter-methods-------------------------
    def get_unit(self):
        return self._unit
    
    def get_values(self):
        return self._values


    def get_intervals(self):
        return self._intervals


    def set_intervals(self, value):
        self._intervals = value


    def del_intervals(self):
        del self._intervals

     
    def get_name(self):
        return self._name


    def get_mr_name(self):
        return self._mr_name

        
    #----------------------private methods of the class------------------------
    
    
    def _create_plot(self, plotobject):
        '''
        sets up a new plot, which is suitable for plotting indicators.
        '''
        
        plotobject.create_new_plot(title = self._title, xlabel='time interval', ylabel='indicator value [' + self._unit + ']')
        
        # make sure that the plot shows all intervals (including those with None-values)
        l = [None] * self._intervals # len(self._data)
        l[0]=0
        l[self._intervals - 1]=0
        plotobject.plot(range(len(self._values)), l, col = 'white', mark='')
        
        logging.debug("Indicator: created new indicator plot")

    
    
    def _plot_period(self, plotobject, fmt=None, minval = None):
        '''
        Uses a given plot-object (@see output.Plot) to create a 2D-plot of the indicator. 
        
        The resulting plot shows the indicator-values on y and 
        the time-intervals on the x-axis. The title and the filename use
        the name of the specific indicator (polymorph). 
        '''
        
        logging.info("Indicator: starting to plot the indicator")
        
        plotobject.create_new_plot(title = self._title,  ylabel='indicator value [' + self._unit + ']')
        
        if minval is not None and self._times is not None and len(self._times) > 0:
            plotobject.plot(self._times[0], minval, col="white",mark='')
            
        plotobject.plot_date(self._times, self._values, fmt=fmt)
        plotobject.save_plot2png(self._exp_title, 'png') 
        
        logging.debug("Indicator: plotted indicator values")  
        
    #----------------------public methods of the class-------------------------
 
    def calculate(self):
        '''
        abstract polymorph method in order to calculate and return the indicator values.
        The calculated values are written to the protected field self._values.
        After calculating the values, the method returns a reference to this field.
        
        @return: list of index values for all time intervals
        '''
        
        pass    
        
    
    def plot(self, plotobject):
        '''
        Uses a given plot-object (@see output.Plot) to create a 2D-plot of the indicator. 
        
        The resulting plot shows the indicator-values on y and 
        the time-intervals on the x-axis. The title and the filename use
        the name of the specific indicator (polymorph). 
        '''
        
        logging.info("Indicator: starting to plot the indicator")
        
        self._create_plot(plotobject)
        plotobject.plot(range(len(self._values)), self._values)     
        plotobject.save_plot2png(self._exp_title, 'png') 
           
        

    def export2csv(self, csvwriter):
        '''
        uses a given csv-writer-object (@see output CSV_export) in export the indicator to csv.
        
        The method constructs the rows for the csv-files with a header row and
        2 colums of data containing the interval and the calculated value.
        @param csvwriter: CSV_export-object used to write the rows
        '''
        
        logging.info("Indicator: starting to export the indicator to a csv-file")
        
        csvwriter.open_writer(self._exp_title +'.csv')
        csvwriter.write(['interval','value'])
        for i in range(len(self._values)):
            csvwriter.write([i,self._values[i]])
        csvwriter.close_writer()
        
        logging.debug("Indicator: finished exporting the indicator to a csv-file")

 
    #--------------assign properties using get and set-methods-----------------
        
    name = property(get_name, None, None, "user friendly name of the indicator (e.g. Buffer Index)")
    mr_name = property(get_mr_name, None, None, "machine readable name of the indicator (e.g. buffer_idx)")
    intervals = property(get_intervals, set_intervals, del_intervals, "number of time intervals")
    values = property(get_values, None, None, "values of the indicator (for every interval)")
    unit = property(get_unit, None, None, "unit of the indicator")
